package com.bloveoa.zkkd.controller;

import com.alibaba.fastjson.JSON;
import com.bloveoa.zkkd.annotation.LimitIp;
import com.bloveoa.zkkd.annotation.ResponseBodyWrapper;
import com.bloveoa.zkkd.doman.OutTokenModel;
import com.bloveoa.zkkd.doman.TransBean;
import com.bloveoa.zkkd.doman.UserModel;
import com.bloveoa.zkkd.exception.CommonException;
import com.bloveoa.zkkd.redis.utils.RedisUtil;
import com.bloveoa.zkkd.service.UserService;
import com.bloveoa.zkkd.service.impl.OutTokenServiceImpl;
import com.bloveoa.zkkd.util.AESCipher;
import com.bloveoa.zkkd.util.NumberUtil;
import com.bloveoa.zkkd.util.R;
import com.bloveoa.zkkd.util.RUtil;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.support.HttpRequestHandlerServlet;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;


import static com.bloveoa.zkkd.util.R.Enum.INPUT_DATA_ERROR;
import static com.bloveoa.zkkd.util.R.Enum.TX_HASH_EXISTS;

@RestController
@RequestMapping("/student")
@ResponseBodyWrapper
@Slf4j
public class OutTokenController {
    private final RedisUtil redisUtil;
    private final OutTokenServiceImpl outTokenService;
    private final UserService userService;

    public OutTokenController(OutTokenServiceImpl outTokenService,
                              RedisUtil redisUtil, UserService userService) {
        this.outTokenService = outTokenService;
        this.redisUtil = redisUtil;
        this.userService = userService;
    }

    @ApiOperation(value = "申请提币")
    @ApiImplicitParams({ // 参数说明
//            @ApiImplicitParam(name = "txHash", required = true, paramType = "query", value = "转eth的hash", dataType = "string"),
//            @ApiImplicitParam(name = "outTokenNum", required = true, paramType = "query", value = "1", dataType = "string"),
            // @ApiImplicitParam(name = "toAddress", required = true, paramType = "query", value = "1", dataType = "string"),
            @ApiImplicitParam(name = "data", required = true, paramType = "query", value = "加密后的数据", dataType = "string"),
    })
    @PostMapping("/saveST")
    public R<OutTokenModel> saveST(String data) {
        //揭秘1
        String s = null;
        try {
            s = AESCipher.decryptAES(data);
        } catch (Exception e) {
            throw new CommonException(INPUT_DATA_ERROR);
        }
        TransBean parse = JSON.parseObject(s, TransBean.class);
        String s1 = redisUtil.get(parse.getToAddress());
        if (!parse.getTime().equals(s1)) {
            throw new CommonException(INPUT_DATA_ERROR);
        }
        if (outTokenService.existsByTxHash(parse.getTxHash())) {
            throw new CommonException(TX_HASH_EXISTS);
        }
        OutTokenModel outTokenModel = new OutTokenModel()
                .setOutTokenNum(new BigDecimal(parse.getOutTokenNum()))
                .setTxHash(parse.getTxHash()).setAddress(parse.getToAddress());
        outTokenService.insertOutToken(outTokenModel);
        UserModel userModel = userService.queryByAddress(parse.getToAddress());
        int i = userModel.getTokenNum() - NumberUtil.getIntByStr(parse.getOutTokenNum());
        userModel.setTokenNum(i);
        userService.saveUser(userModel);
        return RUtil.ok(outTokenModel);
    }

    @ApiOperation(value = "加密")
    @ApiImplicitParams({ // 参数说明
            @ApiImplicitParam(name = "address", required = true, paramType = "query", value = "转token到的地址", dataType = "string"),
    })
     @LimitIp("吃饭了")
    @GetMapping("/findTimeStamp")
    public R<String> findTimeStamp(HttpServletRequest request, String address) throws NoSuchPaddingException, BadPaddingException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IllegalBlockSizeException, UnsupportedEncodingException, InvalidKeyException {
        String data = String.valueOf(System.currentTimeMillis());
//        String realIP = getRealIP(request);
       // System.out.println("realIP="+realIP);
        redisUtil.set(address, data);
        return RUtil.ok(AESCipher.encryptAES(data));
    }
}
